package com.examsys.view;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import java.util.Random;

import javax.swing.DefaultComboBoxModel;
import javax.swing.GroupLayout;
import javax.swing.GroupLayout.Alignment;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JPasswordField;
import javax.swing.JTextField;
import javax.swing.LayoutStyle.ComponentPlacement;
import javax.swing.border.EmptyBorder;

import com.examsys.po.Admin;
import com.examsys.po.Users;
import com.examsys.service.AdminService;
import com.examsys.service.Main;
import com.examsys.service.UsersService;
/**
 * 系统登录窗口
 * @author edu-1
 *
 */
public class LoginDialog extends JDialog {

	private final JPanel contentPanel = new JPanel();
	private JTextField userNameTxf;//用户名输入框
	private JPasswordField passwordPdf;//密码框
	private JComboBox userGroupCbb;//用户组下拉框
	private JLabel codeLbl;//显示验证码的标签
	private JTextField codeTxf;//验证码输入框
	private String rand;//存放生成的验证码
	/**
	 * Create the dialog.
	 */
	public LoginDialog() {
		setTitle("考试系统登录");
		setBounds(100, 100, 303, 267);
		getContentPane().setLayout(new BorderLayout());
		contentPanel.setBorder(new EmptyBorder(5, 5, 5, 5));
		getContentPane().add(contentPanel, BorderLayout.CENTER);
		
		JLabel label = new JLabel("账  号：");
		
		JLabel label_1 = new JLabel("密  码：");
		
		userNameTxf = new JTextField();
		userNameTxf.setColumns(10);
		
		passwordPdf = new JPasswordField();
		
		JLabel label_2 = new JLabel("用户组：");
		
		userGroupCbb = new JComboBox();
		userGroupCbb.setModel(new DefaultComboBoxModel(new String[] {"管理员", "考试者"}));
		
		JLabel label_3 = new JLabel("验证码：");
		
		codeLbl = new JLabel("");
		codeLbl.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseClicked(MouseEvent e) {
				initCode();//初始验证码
			}
		});
		
		codeTxf = new JTextField();
		codeTxf.setColumns(10);
		GroupLayout gl_contentPanel = new GroupLayout(contentPanel);
		gl_contentPanel.setHorizontalGroup(
			gl_contentPanel.createParallelGroup(Alignment.LEADING)
				.addGroup(gl_contentPanel.createSequentialGroup()
					.addGap(22)
					.addGroup(gl_contentPanel.createParallelGroup(Alignment.LEADING)
						.addGroup(gl_contentPanel.createSequentialGroup()
							.addComponent(label)
							.addPreferredGap(ComponentPlacement.RELATED)
							.addComponent(userNameTxf, GroupLayout.PREFERRED_SIZE, 148, GroupLayout.PREFERRED_SIZE))
						.addGroup(gl_contentPanel.createSequentialGroup()
							.addComponent(label_1)
							.addPreferredGap(ComponentPlacement.RELATED)
							.addComponent(passwordPdf, GroupLayout.PREFERRED_SIZE, 148, GroupLayout.PREFERRED_SIZE))
						.addGroup(gl_contentPanel.createSequentialGroup()
							.addComponent(label_2)
							.addPreferredGap(ComponentPlacement.RELATED)
							.addComponent(userGroupCbb, GroupLayout.PREFERRED_SIZE, 83, GroupLayout.PREFERRED_SIZE))
						.addGroup(gl_contentPanel.createSequentialGroup()
							.addComponent(label_3)
							.addPreferredGap(ComponentPlacement.RELATED)
							.addComponent(codeTxf, GroupLayout.PREFERRED_SIZE, 49, GroupLayout.PREFERRED_SIZE)
							.addPreferredGap(ComponentPlacement.UNRELATED)
							.addComponent(codeLbl)))
					.addContainerGap(55, Short.MAX_VALUE))
		);
		gl_contentPanel.setVerticalGroup(
			gl_contentPanel.createParallelGroup(Alignment.LEADING)
				.addGroup(gl_contentPanel.createSequentialGroup()
					.addGap(19)
					.addGroup(gl_contentPanel.createParallelGroup(Alignment.BASELINE)
						.addComponent(label)
						.addComponent(userNameTxf, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE))
					.addGap(26)
					.addGroup(gl_contentPanel.createParallelGroup(Alignment.BASELINE)
						.addComponent(label_1)
						.addComponent(passwordPdf, GroupLayout.PREFERRED_SIZE, 19, GroupLayout.PREFERRED_SIZE))
					.addGap(18)
					.addGroup(gl_contentPanel.createParallelGroup(Alignment.BASELINE)
						.addComponent(label_2)
						.addComponent(userGroupCbb, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE))
					.addGap(18)
					.addGroup(gl_contentPanel.createParallelGroup(Alignment.LEADING)
						.addGroup(gl_contentPanel.createParallelGroup(Alignment.BASELINE)
							.addComponent(label_3)
							.addComponent(codeTxf, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE))
						.addComponent(codeLbl))
					.addContainerGap(23, Short.MAX_VALUE))
		);
		contentPanel.setLayout(gl_contentPanel);
		JPanel buttonPane = new JPanel();
		buttonPane.setLayout(new FlowLayout(FlowLayout.RIGHT));
		getContentPane().add(buttonPane, BorderLayout.SOUTH);
		
		JButton okButton = new JButton("登录");		
		ActionListener loginListener = new LoginListener();//登录监听器对象
		okButton.addActionListener(loginListener);//把监听器设置给按钮
		
		okButton.setActionCommand("OK");
		buttonPane.add(okButton);
		getRootPane().setDefaultButton(okButton);
		
		JButton cancelButton = new JButton("取消");
		cancelButton.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				LoginDialog.this.dispose();//销毁窗口
			}
		});
		cancelButton.setActionCommand("Cancel");
		buttonPane.add(cancelButton);
		
		initCode();//初始验证码
	}
	
	/**
	 * 登录监听器类
	 * @author edu-1
	 *
	 */
	private class LoginListener implements ActionListener{
		
		/**
		 * 当登录按钮被点击时执行此方法
		 */
		public void actionPerformed(ActionEvent e) {
			String userName=userNameTxf.getText();//获取用户名输入框的内容
			String password=new String(passwordPdf.getPassword());//获取密码框内容
			String userGroup=(String)userGroupCbb.getSelectedItem();//获取用户组下拉框选中的项
			String code=codeTxf.getText();//获取验证码输入框内容
			
			final MessageDialog messageDialog=new MessageDialog();//创建信息提示框对象
			if(userName==null||"".equals(userName)){
				messageDialog.setMsg("账号不能为空");
				messageDialog.setVisible(true);//设置信息框可见
				return;
			}
			
			if(password==null||"".equals(password)){
				messageDialog.setMsg("密码不能为空");
				messageDialog.setVisible(true);//设置信息框可见
				return;
			}
			
			if(code==null||"".equals(code)){
				messageDialog.setMsg("验证码不能为空");
				messageDialog.setVisible(true);//设置信息框可见
				return;
			}
			
			if(!rand.equals(code)){//之前存的验证码与用户输入的是否相等
				messageDialog.setMsg("验证码不正确");
				messageDialog.setVisible(true);//设置信息框可见
				return;
			}
			try {
				if("管理员".equals(userGroup)){
					//查找业务逻辑层对象
					AdminService adminService=Main.lookUp("adminService");
					//通过用户名去获取管理员
					Admin dbAdmin = adminService.getAdminByUserName(userName);
					if(dbAdmin==null){//如果拿不到管理员
						messageDialog.setMsg("账号不存在");
						messageDialog.setVisible(true);//设置信息框可见
						return;
					}
					
					if(!password.equals(dbAdmin.getUser_pass())){//验证当前录入的密码与数据库返回来的密码是否相等
						messageDialog.setMsg("密码错误");
						messageDialog.setVisible(true);//设置信息框可见
						return;
					}
					
					Main.admin=dbAdmin;//存放登录成功的管理员对象到全局属性中
					EventQueue.invokeLater(new Runnable() {
						public void run() {
							try {
								messageDialog.dispose();//销毁信息提示对话框
								LoginDialog.this.dispose();//销毁登录对话框
								//管理员主界面
								AdminMainFrame frame = new AdminMainFrame();
								frame.setVisible(true);//设置管理员主界面可见
								
							} catch (Exception e) {
								e.printStackTrace();
							}
						}
					});
				}else{
					//考试者
					//查找业务逻辑层对象
					UsersService usersService=Main.lookUp("usersService");
					//通过用户名去获取考试者
					Users dbUsers = usersService.getUsersByUserName(userName);
					if(dbUsers==null){//如果拿不到考试者
						messageDialog.setMsg("账号不存在");
						messageDialog.setVisible(true);//设置信息框可见
						return;
					}
					
					if(!password.equals(dbUsers.getUser_pass())){//验证当前录入的密码与数据库返回来的密码是否相等
						messageDialog.setMsg("密码错误");
						messageDialog.setVisible(true);//设置信息框可见
						return;
					}
					
					Main.users=dbUsers;//存放登录成功的考试者对象到全局属性
					EventQueue.invokeLater(new Runnable() {
						public void run() {
							try {
								messageDialog.dispose();//销毁信息提示对话框
								LoginDialog.this.dispose();//销毁登录对话框
								//考试者主界面
								UsersMainFrame frame = new UsersMainFrame();
								frame.setVisible(true);//设置考试者主界面可见
							} catch (Exception e) {
								e.printStackTrace();
							}
						}
					});
				}
			} catch (Exception e1) {
				e1.printStackTrace();
				messageDialog.setMsg("登录失败,"+e1.getMessage());
				messageDialog.setVisible(true);//设置提示框为可见
			}
		}
	}
	
	/**
	 * 生成验证码方法
	 */
	private void initCode(){
		Icon icon=null;//背景图
		//在内存中创建图象
        int width = 60, height = 20;
        BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
        //获取图形上下文
        Graphics g = image.getGraphics();
        //生成随机类对象
        Random random = new Random();
        //设定背景色
        g.setColor(getRandColor(200, 250));
        g.fillRect(0, 0, width, height);//从坐标为0，0开始画一个矩形
        //设定字体
        g.setFont(new Font("Times New Roman", Font.PLAIN, 18));
        //随机产生155条干扰线，使图象中的认证码不易被其它程序探测到
        g.setColor(getRandColor(160, 200));//切换颜色
        for (int i = 0; i < 155; i++) {//要生成155条干扰线
            int x = random.nextInt(width);
            int y = random.nextInt(height);
            int xl = random.nextInt(12);
            int yl = random.nextInt(12);
            g.drawLine(x, y, x + xl, y + yl);//在随机坐标处画干扰线
        }
        //取随机产生的认证码(4位数字)
        String sRand = "";
        for (int i = 0; i < 4; i++) {
            String rand = String.valueOf(random.nextInt(10));
            sRand += rand;
            // 将认证码显示到图象中
            g.setColor(new Color(20 + random.nextInt(110), 20 + random.nextInt(110), 20 + random.nextInt(110)));
            //调用函数出来的颜色相同，可能是因为种子太接近，所以只能直接生成
            g.drawString(rand, 13 * i + 6, 16);
        }
        //将认证码存入属性rand
        rand=sRand;
        //图象生效
        g.dispose();
        
        //生成一张图片
        Image img = image.getScaledInstance(width, height, Image.SCALE_AREA_AVERAGING);
		icon=new ImageIcon(img);//把图片类型转换一下，变成icon类型的图
        
		codeLbl.setIcon(icon);//给验证码标签设置背景图
	}
	
	
	 /*
     * 给定范围获得随机颜色
     */
    private Color getRandColor(int fc, int bc) {
        Random random = new Random();
        if (fc > 255) {
            fc = 255;
        }
        if (bc > 255) {
            bc = 255;
        }
        int r = fc + random.nextInt(bc - fc);
        int g = fc + random.nextInt(bc - fc);
        int b = fc + random.nextInt(bc - fc);
        return new Color(r, g, b);
    }

	
}
